0001
0009 import Foundation
0010
0011 extension BigUInt {
0012
0014 Complexity @warn_unused_result
0018 public static func gcd(a: BigUInt, _ b: BigUInt) -> BigUInt {
0019 https://en.wikipedia.org/wiki/Binary_GCD_algorithm if a.isZero || b.isZero { return BigUInt() }
0021
0022 let az = a.trailingZeroes
0023 let bz = b.trailingZeroes
0024 let twos = min(az, bz)
0025
0026 var (x, y) = (a >> az, b >> bz)
0027 if x < y { swap(&x, &y) }
0028
0029 while !x.isZero {
0030 x >>= x.trailingZeroes
0031 if x < y { swap(&x, &y) }
0032 x -= y
0033 }
0034 return y << twos
0035 }
0036
0037 Returns Complexity @warn_unused_result
0045 public func inverse(modulus: BigUInt) -> BigUInt? {
0046 var t1 = BigInt(0)
0047 var t2 = BigInt(1)
0048 var r1 = modulus
0049 var r2 = self
0050 while !r2.isZero {
0051 let quotient = r1 / r2
0052 (t1, t2) = (t2, t1 - BigInt(quotient) * t2)
0053 (r1, r2) = (r2, r1 - quotient * r2)
0054 }
0055 if r1 > 1 { return nil }
0056 if t1.negative { return modulus - t1.abs }
0057 return t1.abs
0058 }
0059 }